#ifndef TSMP_API_H
#define TSMP_API_H

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /*memcpy*/
#include <strings.h>/*bzero*/
// #include <pcap.h>

#include <arpa/inet.h>/*htons,ntohs*/
#include <endian.h>   /*htobeXX,beXXtoh,htoleXX,leXXtoh*/
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
// #include <linux/in.h>/*struct sockaddr_in*/
#include <linux/filter.h>
#include <linux/if_ether.h>/*struct ethhdr*/
#include <linux/ip.h>      /*struct iphdr*/
#include <net/if.h>
#include <netpacket/packet.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/time.h>

#include "sim.h"
#include "tsmp_addr.h"
#include "tsmp_type.h"

#define CNCAPI_DEBUG 1
// #undef CNCAPI_DEBUG

#if CNCAPI_DEBUG
#define CNCAPI_DBG(args...)  \
  do                         \
  {                          \
    printf("CNCAPI-INFO: "); \
    printf(args);            \
  } while (0)
#define CNCAPI_ERR(args...)   \
  do                          \
  {                           \
    printf("CNCAPI-ERROR: "); \
    printf(args);             \
    exit(0);                  \
  } while (0)
#else
#define CNCAPI_DBG(args...)
#define CNCAPI_ERR(args...)
#endif

// #define write_debug_msg(format,...){printf(format,##__VA_ARGS__);FILE*fp =
// fopen("debug_log.txt","a+");if(fp!=NULL){fwrite(format,sizeof(char),strlen(format),fp);fclose(fp);}}

#define DEBUG_BUFFER_MAX 4096

#define write_debug_msg(format, ...)                           \
  {                                                            \
    char buffer[DEBUG_BUFFER_MAX + 1] = {0};                   \
    snprintf(buffer, DEBUG_BUFFER_MAX, format, ##__VA_ARGS__); \
    FILE *fp = fopen("debug_log.txt", "a+");                   \
    if (fp != NULL)                                            \
    {                                                          \
      fwrite(buffer, strlen(buffer), 1, fp);                   \
    };                                                         \
    fclose(fp);                                                \
  }

#define SIM_DEBUG_BUFFER_MAX 4096
#define sim_write_debug_msg(format, ...)                           \
  {                                                                \
    char buffer[SIM_DEBUG_BUFFER_MAX + 1] = {0};                   \
    snprintf(buffer, SIM_DEBUG_BUFFER_MAX, format, ##__VA_ARGS__); \
    FILE *fp = fopen("sim_debug_log.txt", "a+");                   \
    if (fp != NULL)                                                \
    {                                                              \
      fwrite(buffer, strlen(buffer), 1, fp);                       \
    };                                                             \
    fclose(fp);                                                    \
  }

/**************数据发送接收相关API**************/

int tsmp_pkt_send_recv_init(u8 *net_interface, struct sock_fprog filter);
int tsmp_pkt_send_recv_destroy();

// 数据报文发送处理函数
int tsmp_pkt_send_handle(u8 *pkt, u16 len);

// 数据报文接收处理函数（每次只抓一个包）返回接收的报文的指针
u8 *tsmp_pkt_receive_dispatch_1(u16 *len);

/**************调试工具相关API**************/
// 报文打印
void cnc_pkt_print(u8 *pkt, int len);

// 64bit主机序转网络序
u64 htonll(u64 value);

/**************配置相关API**************/
int set_controller_mac(u16 mid, CONTROLLER_APP_TYPE type);

void get_hcp_mac_from_mid(u8 *mac, u16 mid);
void get_controller_mac_from_mid(u8 *mac, u16 mid, CONTROLLER_APP_TYPE type);
u16 get_mid_from_mac(u8 *mac);

int cfg_hw_state(u8 *local_mac, u32 state, u8 *pkt);

int tsmp_cfg_hcp_tsnlight_mid(u8 *mac, u16 hcp_mid, u16 tsnlight_mid, u8 *pkt);

int tsmp_set_req(u8 *local_mac, u16 data_num, u32 addr, u8 *pkt);
int tsmp_get_req(u8 *local_mac, u16 data_num, u32 addr, u8 *pkt);
u32 *tsmp_get_res(u8 *local_mac, u16 data_num, u32 addr);
int cfg_varify(u8 *local_mac, u16 data_num, u32 addr, u8 *pkt);
int rc_cfg_varify(u8 *local_mac, u16 data_num, u32 addr, u8 *pkt);
int rc_st_cfg_varify(u8 *local_mac, u16 data_num, u32 addr, u8 *pkt);
int cfg_hw_state(u8 *local_mac, u32 state, u8 *pkt);

int tunnel_pkt_malloc();
void tunnel_pkt_free();
int tsmp_tunnal_encapsulation(u8 *local_mac, u16 length, u8 *igmp_pkt);

#endif
